package com.irssproject.app.bean.clustering;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ClusterNode {
	 
    public String valor;
    public List<ClusterNode> children;
 
    /**
     * Default ctor.
     */
    public ClusterNode() {
        super();
    }
 
    /**
     * Convenience ctor to create a Node<T> with an instance of T.
     * @param valor an instance of T.
     */
    public ClusterNode(String valor) {
        this();
        setValor(valor);
    }
     
    /**
     * Return the children of Node<T>. The Tree<T> is represented by a single
     * root Node<T> whose children are represented by a List<Node<T>>. Each of
     * these Node<T> elements in the List can have children. The getChildren()
     * method will return the children of a Node<T>.
     * @return the children of Node<T>
     */
    public List<ClusterNode> getChildren() {
        if (this.children == null) {
            return new ArrayList<ClusterNode>();
        }
        return this.children;
    }
 
    /**
     * Sets the children of a Node<T> object. See docs for getChildren() for
     * more information.
     * @param children the List<Node<T>> to set.
     */
    public void setChildren(List<ClusterNode> children) {
        this.children = children;
    }
 
    /**
     * Returns the number of immediate children of this Node<T>.
     * @return the number of immediate children.
     */
    public int getNumberOfChildren() {
        if (children == null) {
            return 0;
        }
        return children.size();
    }
     
    /**
     * Adds a child to the list of children for this Node<T>. The addition of
     * the first child will create a new List<Node<T>>.
     * @param child a Node<T> object to set.
     */
    public void addChild(ClusterNode child) {
        if (children == null) {
            children = new ArrayList<ClusterNode>();
        }
        children.add(child);
    }
     
    /**
     * Inserts a Node<T> at the specified position in the child list. Will     * throw an ArrayIndexOutOfBoundsException if the index does not exist.
     * @param index the position to insert at.
     * @param child the Node<T> object to insert.
     * @throws IndexOutOfBoundsException if thrown.
     */
    public void insertChildAt(int index, ClusterNode child) throws IndexOutOfBoundsException {
        if (index == getNumberOfChildren()) {
            // this is really an append
            addChild(child);
            return;
        } else {
            children.get(index); //just to throw the exception, and stop here
            children.add(index, child);
        }
    }
     
    /**
     * Remove the Node<T> element at index index of the List<Node<T>>.
     * @param index the index of the element to delete.
     * @throws IndexOutOfBoundsException if thrown.
     */
    public void removeChildAt(int index) throws IndexOutOfBoundsException {
        children.remove(index);
    }
 
    public String getValor() {
        return this.valor;
    }
 
    public void setValor(String valor) {
        this.valor = valor;
    }
     
    public String toString() {
	    try{
		        StringBuilder sb = new StringBuilder();
		        sb.append("{").append(getValor().toString()).append(",[");
		        int i = 0;
		        for (ClusterNode e : getChildren()) {
		            if (i > 0) {
		                sb.append(",");
		            }
		            sb.append(e.getValor().toString());
		            i++;
		        }
		        sb.append("]").append("}");
		        return sb.toString();
	    }
	    catch(Exception e)
	    {
		    return "";
	    }
    }

	public boolean containsNodeWithValor(String valor) {

		if (this.getValor().equals(valor))
		{
			return true;
		}
		else
		{
			Iterator <ClusterNode> itClNode = this.getChildren().iterator();
			while(itClNode.hasNext())
			{
				ClusterNode clNode = itClNode.next();
				if (clNode.containsNodeWithValor(valor))
				{
					return true;
				}
				
			}
			return false;
		}
				
	}

	public boolean isEqual(ClusterNode act2) {

		if (this.getValor().equals(act2.getValor()))
		{
			return true;
		}
		else
		{
			Iterator <ClusterNode> itClNode = this.getChildren().iterator();
			while(itClNode.hasNext())
			{
				ClusterNode clNode = itClNode.next();
				if (clNode.isEqual(act2))
				{
					return true;
				}
				
			}
			return false;
		}	
		
	}

    /**
     * Adds the children to 'this' node.
     * if one of the childs exists yet, we don't add it.
     * @param children the List<Node<T>> to add.
     */

	public void addChildren(List<ClusterNode> children)
	{
		for (int i=0;i<children.size();i++)
		{
			boolean jahies = false;

			Iterator<ClusterNode> itFillsThis = this.getChildren().iterator();
			
			ClusterNode candidatActual = children.get(i);
			
			while (itFillsThis.hasNext() && jahies == false)
			{
				ClusterNode fillThisActual = itFillsThis.next();
				
				if (candidatActual.getValor()!=null)
				{
					if (candidatActual.getValor().equals(fillThisActual.getValor()))
					{
						//No afegirem
						jahies = true;
					}
				}
			}
			
			if (jahies == false)
			{
				this.addChild(candidatActual);
			}
		}
	
	}
}